// #define  _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdbool.h>


#include "../utils/config.h"
#include "unit.h"


/*------------------加载unit---------------------*/
// 解析service unit文件中的服务配置项
static void parse_unit_service(void* user,const char *section,const char *key,char *value){
    Service *svc=(Service *)user;
    if (strcmp(section,"Unit")==0 && strcmp(key,"Description")==0)
    {
        svc->description=strdup(value);
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"After")==0)
    {
        trim(value);
        svc->afterbyname=str_split(value,",",4096);
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"Before")==0)
    {
        trim(value);
        svc->beforebyname=str_split(value,",",4096);
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"Wants")==0)
    {
        trim(value);
        svc->wantsbyname=str_split(value,",",4096);
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"Requires")==0)
    {
        trim(value);
        svc->requires=str_split(value,",",4096);
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"Environment")==0)
    {
        trim(value);
        svc->environ=str_split(value,",",4096);
    }else if (strcmp(section,"Install")==0 && strcmp(key,"WantedBy")==0)
    {
        trim(value);
        svc->install=strdup(value);
    }else if (strcmp(section,"Service")==0 && strcmp(key,"ExecStart")==0)
    {
        (svc->argv!=NULL)?0:str_free(svc->argv);
        svc->argv=str_split(value," ",4096);
        svc->binname=calloc(1024,1);
        svc->binpath=calloc(1024,1);
        split_dir_file(NULL,svc->binname,svc->argv[0]);
        strcpy(svc->binpath,svc->argv[0]);
        strcpy(svc->argv[0],svc->binname);
    }else if (strcmp(section,"Service")==0 && strcmp(key,"Stdin")==0)
    {
        trim(value);
        svc->std_in=strdup(value);
    }else if (strcmp(section,"Service")==0 && strcmp(key,"Stdout")==0)
    {
        trim(value);
        svc->std_out=strdup(value);
    }else if (strcmp(section,"Service")==0 && strcmp(key,"Stderr")==0)
    {
        trim(value);
        svc->std_err=strdup(value);
    }else if (strcmp(section,"Service")==0 && strcmp(key,"Type")==0)
    {
        trim(value);
        if (strcmp(value,"notify")==0)
        {
            svc->start_type=1;
        }else if (strcmp(value,"dbus")==0)
        {
            svc->start_type=2;
        }else{
            svc->start_type=0;
        }   
    }
}

// 解析target unit文件中的目标配置项
static void parse_unit_target(void* user,const char *section,const char *key,char *value){
    Target *target=(Target *)user;  // 将用户数据转换为unit_def结构体指针
    
    // 处理[Unit]段落的Description键
    if (strcmp(section,"Unit")==0 && strcmp(key,"Description")==0)
    {
        // 为description字段分配内存并复制值
        target->description=calloc(strlen(value)+1,1);  // +1为null终止符预留空间
        strcpy(target->description,value);  // 复制描述字符串
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"After")==0)
    {
        trim(value);  // 去除value两端的空白字符
        // 为wantedbyname字段分配内存(但未复制值，可能是代码不完整)
        target->wantsbyname=str_split(value,",",4096);
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"Before")==0)
    {
        trim(value);
        target->beforebyname=str_split(value,",",4096);
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"Wants")==0)
    {
        trim(value);
        target->wantsbyname=str_split(value,",",4096);    
    }else if (strcmp(section,"Unit")==0 && strcmp(key,"Requires")==0)
    {
        trim(value);
        target->requires=str_split(value,",",4096);
    }else if (strcmp(section,"Install")==0 && strcmp(key,"WantedBy")==0)
    {
        trim(value);
        target->install=strdup(value);
    }
}

/**
 * Load unit definition from configuration file
 * @param unit Pointer to unit definition structure to be filled
 * @param path Path to configuration file
 * @return 0 on success, negative error code on failure
 *   -EINVAL: invalid parameters
 *   -ENOENT: file not found or cannot be accessed
 *   -EPARSE: parse error
 */
Unit *unitLoadFrom(const char *path) {
    if (!path) {
        return NULL;
    }

    // 检查文件是否存在和可读
    if (access(path, R_OK) != 0) {
        return NULL;
    }

    
    // 根据文件扩展名确定unit类型
    if (str_has_suffix(path,".service"))
    {
        Service *svc=(Service *)calloc(1,sizeof(Service));
        svc->meta.type = UNIT_SERVICE;
        svc->meta.dir=calloc(3072,1);
        svc->meta.name=calloc(1024,1);
        split_dir_file(svc->meta.dir,svc->meta.name,path);
         // 解析配置文件
        if (ini_mmap_parse(svc, path, parse_unit_service, &svc->meta.m_time) < 0) {
            fprintf(stderr, "Error: Failed to parse unit file %s\n", path);
            free(svc);
            return NULL;
        }
        return (Unit *)svc;
    }else if (str_has_suffix(path,".target"))
    {
        Target *target=(Target *)calloc(1,sizeof(Target));
        target->meta.type = UNIT_TARGET;
        target->meta.dir=calloc(3072,1);
        target->meta.name=calloc(1024,1);
        split_dir_file(target->meta.dir,target->meta.name,path);
         // 解析配置文件
        if (ini_mmap_parse(target, path, parse_unit_target, &target->meta.m_time) < 0) {
            fprintf(stderr, "Error: Failed to parse unit file %s\n", path);
            free(target);
            return NULL;
        }
        return (Unit *)target;
    }
    return NULL;
}

/*------------------查找unit-*/
/**
 * Check if unit has a given name
 * @param unit unit_def 结构体指针
 * @param name 字符串指针
 * @return 1 若unit的name字段与name相同, 0 否则
 *   -EINVAL: 非法参数
 *   -EPERM: 操作不允许
 */
int unitHasName(const Unit *unit, const char *name) {
    if (!unit || !name) {
        return -EINVAL;
    }
    if (unit->type == UNIT_SERVICE) {
        return (strcmp(unit->name, name) == 0);
    } else if (unit->type == UNIT_TARGET) {
        return (strcmp(unit->name, name) == 0);
    }
    return -EINVAL;
}

/*
 * Check if unit is active
 * @param unit unit_def 结构体指针
 * @return 1 若unit的state字段为UNIT_ACTIVE, 0 否则
 *   -EINVAL: 非法参数
*/
int unitIsActive(const Unit *unit) {
    if (!unit) {
        return -EINVAL;
    }
    return (unit->state == UNIT_ACTIVE);
}

// 判断unit的依赖项requires是否active
bool unitDependencyRequiresOk(const Unit *unit) {
    if (!unit) {
        return false;
    }
    for (size_t i = 0; i < unit->requires_size; i++)
    {
        Unit *dep=hashmap_get(unit->dependencies,unit->requires[i]);
        if (dep==NULL && dep->state!=UNIT_ACTIVE)
        {
            return false;
        }  
    }
    return true;
}

// //------------------事务---------------------
// TransactionState  driveTranstion(Transaction *trans) {
//     if (!trans) {
//         return TRANSACTION_ERROR;
//     }
//     switch (trans->state)
//     {
//     case TRANSACTION_COMPLETE:
//         printf("Transaction complete: %s\n",trans->obj->name);
//         break;
//     case TRANSACTION_START:
//         if (trans->obj->type==UNIT_SERVICE)
//         {
//             service_start((Service*)trans->obj);
//         }else if (trans->obj->type==UNIT_TARGET)
//         {
//             target_start((Target*)trans->obj);
//         }
//         printf("Transaction start: %s\n",trans->obj->name);
//         trans->state=TRANSACTION_WAIT;
//         break;
//     case TRANSACTION_STOP:
//         if (trans->obj->type==UNIT_SERVICE)
//         {
//             service_stop((Service*)trans->obj); 
//         }else if (trans->obj->type==UNIT_TARGET)    
//         {
//             target_stop((Target*)trans->obj);
//         }
//         printf("Transaction stop: %s\n",trans->obj->name);
//         trans->state=TRANSACTION_WAIT;
//         break;
//     case TRANSACTION_ERROR:
//         printf("Transaction error: %s\n",trans->obj->name);
//         break;
//     case TRANSACTION_WAIT:
//         printf("Transaction wait: %s\n",trans->obj->name);
//         if (unitDependencyRequiresOk(trans->obj))
//         {
//             trans->state=TRANSACTION_START;
//         }else{
//             trans->state=TRANSACTION_WAIT;
//         }
//         break;
//     case TRANSACTION_RESTART:
//         printf("Transaction restart: %s\n",trans->obj->name);
//         trans->state=TRANSACTION_COMPLETE;
//         break;
//     case TRANSACTION_RELOAD:
//         printf("Transaction reload: %s\n",trans->obj->name);
//         trans->state=TRANSACTION_COMPLETE;
//         break;
//     default:
//         printf("Transaction unknown: %s\n",trans->obj->name);
//         trans->state=TRANSACTION_ERROR;
//         break;
//     }
//     return trans->state;
// }

//------------------unit数组-   
/*
 * Initialize unit array
 * @param unitarry unitArray 结构体指针
 * @param size 数组大小
 * @return 0 on success, negative error code on failure
 *   -EINVAL: invalid parameters
*/
int unitArrayInit(UnitArray * unitarry,unsigned int size) {
    if (!unitarry || size <= 0) {
        return -EINVAL;
    }
    unitarry->size = 0;
    unitarry->capacity = size;
    unitarry->units = (Unit *)calloc(size, sizeof(Unit));
    return 0;
}

// 向unit数组中添加unit
int unitArrayAdd(UnitArray * unitarry, Unit *unit) {
    if (!unitarry || !unit) {
        return -EINVAL;
    }
    if (unitarry->size >= unitarry->capacity) {
        return -EPERM;
    }
    unitarry->units[unitarry->size] = *unit;
    unitarry->size++;
    return 0;
}

// 更新unit数组中指定位置的unit
int unitArrayUpdate(UnitArray * unitarry, int index, Unit *unit) {
    if (!unitarry || index < 0 || index >= unitarry->size || !unit) {
        return -EINVAL;
    }
    unitarry->units[index] = *unit;
    return 0;
}

// 获取unit数组中指定位置的unit
int unitArrayGet(UnitArray * unitarry, int index, Unit *unit) {
    if (!unitarry || index < 0 || index >= unitarry->size || !unit) {
        return -EINVAL;
    }
    *unit = unitarry->units[index];  // 复制unit_def结构体
    return 0;
}

// // 释放unit数组
// int unitArrayFree(UnitArray * unitarry) {
//     if (!unitarry) {
//         return -EINVAL; // 非法参数
//     }
//     for (int i = 0; i < unitarry->size; i++) {
//         unitFree(&unitarry->units[i]);
//     }
//     free(unitarry->units);
//     unitarry->units = NULL;
//     unitarry->size = 0;
//     unitarry->capacity = 0;
//     return 0;
// }

// // 释放unit_def数组
// int unitArrayFreePtr(Unit **units, unsigned int size) {  // 释放unit_def数组
//     if (!units || size <= 0) {
//         return -EINVAL;
//     }
//     for (int i = 0; i < size; i++) {
//         unitFree(units[i]);
//     }
//     free(units);
//     units = NULL;    // 置空指针
//     return 0;
// }

/**
 * Add a dependency to a unit
 * @param unit unit_def 结构体指针
 * @param dependency unit_def 结构体指针
 * @param is_required 是否是依赖项
 * @param is_after 是否是after项
 * @return 0 on success, negative error code on failure
//  */
// int unitAddAfter(Unit *unit, Unit *dependency, DependencyType type) {
//     if (!unit || !dependency) {
//         return -EINVAL; // 非法参数
//     }

//     switch (type)
//     {
//     case DEPENDENCY_WANTS:
//         // 向unit的wants字段中添加依赖项
//         Dependency *new_dependency=(Dependency *)malloc(sizeof(Dependency));
//         new_dependency->unit=dependency;
//         new_dependency->type=DEPENDENCY_WANTS;
//         new_dependency->next=unit->After;
//         unit->After=new_dependency;
//     case DEPENDENCY_REQUIRES:
//         break;
    
//     default:
//         break;
//     }
//     return 0;
// }

